/**
 * Octopus, an XMMS2 client.
 * Copyright (C) 2014 Octopus Team
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

namespace OctopusMx {
	using Octopus;
	public class MxFrameTrack : Mx.Frame {
		public Track  track_model            { get; construct; }
		public string background_style_class { get; construct; }
		public string overlay_style_class    { get; construct; }
		private bool _selected = false;  //store selected state
		public bool selected {
			get {	return _selected;
				}
			set {	if (value) {
						//select
						if (!this.track_overlay.style_pseudo_class_contains ("selected")) {
							this.track_overlay.style_pseudo_class_add ("selected");
						}
					} else {
						//unselect
						if (this.track_overlay.style_pseudo_class_contains ("selected")) {
							this.track_overlay.style_pseudo_class_remove ("selected");
						}
					}
					_selected = value;
				}
		}

		public signal void drop_move ();
		public signal void drop_copy ();
		public signal void drop_insert ();

		private Mx.Stack track_stack;
		private Mx.Frame track_content;
		private Mx.Frame track_overlay;
		private Mx.Frame track_mouse_over_menu;
		private Mx.Frame drag_handle;
		private Clutter.DropAction drop_action;
		internal static Clutter.Actor? button_press_actor = null;

		public MxFrameTrack (Track track_model, string background_style_class, string overlay_style_class) {
			Object(track_model: track_model, background_style_class: background_style_class, overlay_style_class: overlay_style_class);
		}

		construct {
			this.track_stack = new Mx.Stack ();
			this.add_child (this.track_stack);
			this.track_content = new Mx.Frame ();
			this.track_content.style_class = background_style_class;
			this.track_stack.add_child (this.track_content);
			this.track_overlay = new Mx.Frame ();
			this.track_overlay.reactive = true;
			this.track_overlay.style_class = overlay_style_class;
			this.track_stack.add_child (this.track_overlay);
			this.track_mouse_over_menu = new Mx.Frame ();
			this.track_mouse_over_menu.visible = false;
			this.track_overlay.add_child (this.track_mouse_over_menu);
			this.drag_handle = new Mx.Frame ();

			this.button_press_event.connect ((/*Clutter.ButtonEvent*/ event, user_data) => {
				button_press_actor = this;
				return false; //propagate
			});

			this.button_release_event.connect ((/*Clutter.ButtonEvent*/ event, user_data) => {
				//block event when button_press actor != button_release actor
				if (button_press_actor != this) {
					MxTracklist.drag_and_drop_status = MxTracklist.DragAndDropStatus.NONE;
					return true; //stop
				} else {
					return false; //propagate
				}
			});

			this.enter_event.connect ((/*Clutter.CrossingEvent*/ event, user_data) => {
				this.track_mouse_over_menu.visible = true;
				return false; //propagate
			});

			this.leave_event.connect ((/*Clutter.CrossingEvent*/ event, user_data) => {
				this.track_mouse_over_menu.visible = false;
				return false; //propagate
			});
		}

		public override void destroy () {
			base.destroy ();
		}

		public Mx.Frame get_track_content () {
			return track_content;
		}

		public Mx.Frame get_track_mouse_over_menu () {
			return track_mouse_over_menu;
		}

		public Mx.Frame get_drag_handle () {
			return drag_handle;
		}

		private void drop_indicator_remove () {
			track_overlay.style_pseudo_class_remove ("drop-indicator");
		}

		private void drop_indicator () {
			track_overlay.style_pseudo_class_add ("drop-indicator");
		}

		public bool is_active () {
			return track_overlay.style_pseudo_class_contains ("active");
		}

		public void remove_active () {
			track_overlay.style_pseudo_class_remove ("active");
		}

		public void remove_hover () {
			track_overlay.style_pseudo_class_remove ("hover");
		}

/**********************************************************************/
/* drag and drop                                                      */
/**********************************************************************/
		public void enable_drop_action () {
			drop_action = new Clutter.DropAction ();
			drop_action.over_in.connect ((/*Clutter.DropAction*/ action,
			                              /*Clutter.Actor*/      actor) => {
				drop_indicator ();
			});
			drop_action.over_out.connect ((/*Clutter.DropAction*/ action,
			                               /*Clutter.Actor*/      actor) => {
				drop_indicator_remove ();
			});
			drop_action.drop.connect ((/*Clutter.DropAction*/ action,
			                           /*Clutter.Actor*/      actor,
			                           /*gfloat*/             event_x,
			                           /*gfloat*/             event_y) => {
				drop_indicator_remove ();

				//if (this.get_parent () == Global.get ().dragActor) {
				if (this.get_parent () == MxTracklist.drag_actor) {
					//check status for move or copy
					if (MxTracklist.drag_and_drop_status == MxTracklist.DragAndDropStatus.DRAG_MOVE) {
						drop_move ();
					} else {
						drop_copy ();
					}
				} else {
					//insert
					drop_insert ();
				}
				MxTracklist.drag_and_drop_status = MxTracklist.DragAndDropStatus.DROP_SUCCESS;
			});
			this.track_overlay.add_action (drop_action);
		}
	}
}
